﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Driver;
using Project.Core.Common;
using Project.Core.DAL;
using Project.Core.IRepository.Base;
using Project.Core.Model;
using SqlSugar;

namespace Project.Core.Repository.Base
{
    public class BaseRepository<T> : IBaseRepository<T> where T : BaseModel, new()
    {
        private DbContext context;
        private SqlSugarClient db;
        private SimpleClient<T> entityDB;

        internal SqlSugarClient Db
        {
            get { return db; }
            private set { db = value; }
        }

        public DbContext Context
        {
            get { return context; }
            set { context = value; }
        }

        public BaseRepository()
        {
            db = new SqlSugarClient(new ConnectionConfig()
            {
                ConnectionString = BaseDBConfig.ConnectionString,
                DbType = SqlSugar.DbType.MySql,
                IsAutoCloseConnection = true
            });
            //DbContext.Init(BaseDBConfig.ConnectionString);
            //context = DbContext.GetDbContext();
            //db = context.Db;
            //entityDB = context.GetEntityDB<T>(db);
        }

        //public override void SetCollection()
        //{
        //    AsyncCollection = AsyncMongoDataBase.GetCollection<T>(typeof(T).Name);
        //}

        #region 增
        /// <summary>
        /// 同步插入数据
        /// </summary>
        /// <param name="document"></param>
        /// <returns></returns>
        public async Task<int> Insert(T Entity)
        {
            var i = await db.Insertable(Entity).ExecuteReturnBigIdentityAsync();
            return i.ObjToInt();
        }
        #endregion

        #region 删
        public async Task<bool> Delete(T Entity)
        {
            var i = await db.Deleteable(Entity).ExecuteCommandAsync();
            return i > 0;
        }

        public async Task<bool> Delete(int Id)
        {
            var i = await db.Deleteable<T>().In(Id).ExecuteCommandAsync();
            return i > 0;
        }
        #endregion

        #region 改
        public async Task<bool> Update(T Entity)
        {
            var i = await db.Updateable(Entity).ExecuteCommandAsync();
            return i > 0;
        }
        #endregion

        #region 查
        public async Task<List<T>> Query(Expression<Func<T, bool>> expression)
        {
            return await db.Queryable<T>().Where(expression).ToListAsync();
        }

        public async Task<PageDataList<T>> QueryByCondition(Expression<Func<T, bool>> expression, bool IsPage, int PageIndex, int PageSize, Expression<Func<T, object>> orderExpression, bool isAsc)
        {
            int totalCount = 0;
            var list = db.Queryable<T>().Where(expression);
            totalCount = await list.CountAsync();
            List<T> resList = null;
            if (IsPage)
                resList = await list.OrderBy(orderExpression, isAsc ? OrderByType.Asc : OrderByType.Desc).ToPageListAsync(PageIndex, PageSize);
            else
                resList = await list.ToListAsync();

            PageDataList<T> pageDataList = new PageDataList<T>(resList)
            {
                TotalCount = totalCount
            };

            return pageDataList;
        }

        public async Task<T> Find(Expression<Func<T, bool>> expression)
        {
            var Entity = await db.Queryable<T>().FirstAsync(expression);

            return Entity;
        }
        #endregion


        #region mongoDB 方法
        /// <summary>
        /// 异步插入
        /// </summary>
        /// <param name="Entity">实体</param>
        /// <returns></returns>
        //public async Task<bool> InsertAsyncOneData(T Entity)
        //{
        //    try
        //    {
        //        if (AsyncCollection != null)
        //        {
        //            await AsyncCollection.InsertOneAsync(Entity);
        //            return true;
        //        }
        //        else
        //        {
        //            return false;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        return false;
        //    }
        //}

        /// <summary>
        /// 同步插入多条数据
        /// </summary>
        /// <param name="Entitys">多个实体</param>
        /// <returns></returns>
        //public bool InsertManyData(IEnumerable<T> Entitys)
        //{
        //    try
        //    {
        //        //documents = Enumerable.Range(0, 100).Select(i => new BsonDocument("counter", i));
        //        if (AsyncCollection != null)
        //        {
        //            AsyncCollection.InsertMany(Entitys);
        //            return true;
        //        }
        //        else
        //        {
        //            return false;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        return false;
        //    }

        //}

        /// <summary>
        /// 异步插入多条数据
        /// </summary>
        /// <param name="documents"></param>
        /// <returns></returns>
        //public async Task<bool> InsertAsyncManyData(IEnumerable<T> Entitys)
        //{
        //    try
        //    {
        //        //documents = Enumerable.Range(0, 100).Select(i => new BsonDocument("counter", i));
        //        if (AsyncCollection != null)
        //        {
        //            await AsyncCollection.InsertManyAsync(Entitys);
        //            return true;
        //        }
        //        else
        //        {
        //            return false;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        return false;
        //    }
        //}
        /// <summary>
        /// 同步删除
        /// </summary>
        /// <param name="Entity">实体</param>
        /// <returns></returns>
        //public bool Delete(T Entity)
        //{
        //    try
        //    {
        //        if (AsyncCollection != null)
        //        {
        //            AsyncCollection.DeleteOne(k => k._id == Entity._id);
        //            return true;
        //        }
        //        else
        //        {
        //            return false;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        return false;
        //    }
        //}

        /// <summary>
        /// 异步删除
        /// </summary>
        /// <param name="Entity">实体</param>
        /// <returns></returns>
        //public async Task<bool> DeleteAsync(T Entity)
        //{
        //    try
        //    {
        //        if (AsyncCollection != null)
        //        {
        //            await AsyncCollection.DeleteOneAsync(k => k._id == Entity._id);
        //            return true;
        //        }
        //        else
        //        {
        //            return false;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        return false;
        //    }
        //}

        /// <summary>
        /// 异步删除
        /// </summary>
        /// <param name="id">ID</param>
        /// <returns></returns>
        //public async Task<bool> DeleteByIdAsync(int _id)
        //{
        //    try
        //    {
        //        if (AsyncCollection != null)
        //        {
        //            await AsyncCollection.DeleteOneAsync(k => k._id == _id);
        //            return true;
        //        }
        //        else
        //        {
        //            return false;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        return false;
        //    }
        //}

        /// <summary>
        /// 同步删除
        /// </summary>
        /// <param name="id">ID</param>
        /// <returns></returns>
        //public bool DeleteById(int _id)
        //{
        //    try
        //    {
        //        if (AsyncCollection != null)
        //        {
        //            AsyncCollection.DeleteOne(k => k._id == _id);
        //            return true;
        //        }
        //        else
        //        {
        //            return false;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        return false;
        //    }
        //}

        /// <summary>
        /// 异步多个删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        //public async Task<bool> DeleteByIds(int[] _ids)
        //{
        //    try
        //    {
        //        if (AsyncCollection != null)
        //        {
        //            await AsyncCollection.DeleteManyAsync(k => _ids.Contains(k._id));
        //            return true;
        //        }
        //        else
        //        {
        //            return false;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        return false;
        //    }
        //}

        /// <summary>
        /// 同步多个删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        //public bool DeleteByIdsAsync(int[] _ids)
        //{
        //    try
        //    {
        //        if (AsyncCollection != null)
        //        {
        //            AsyncCollection.DeleteMany(k => _ids.Contains(k._id));
        //            return true;
        //        }
        //        else
        //        {
        //            return false;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        return false;
        //    }
        //}
        /// <summary>
        /// 同步更新
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="update"></param>
        /// <returns></returns>
        //public bool Update(Expression<Func<T, bool>> filter, UpdateDefinition<T> update)
        //{
        //    try
        //    {
        //        if (AsyncCollection != null)
        //        {
        //            AsyncCollection.FindOneAndUpdate(filter, update);
        //            return true;
        //        }
        //        else
        //        {
        //            return false;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        return false;
        //    }
        //}

        /// <summary>
        /// 异步更新
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="update"></param>
        /// <returns></returns>
        //public async Task<bool> UpdateAsync(Expression<Func<T, bool>> filter, UpdateDefinition<T> update)
        //{
        //    try
        //    {
        //        if (AsyncCollection != null)
        //        {
        //            await AsyncCollection.FindOneAndUpdateAsync(filter, update);
        //            return true;
        //        }
        //        else
        //        {
        //            return false;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        return false;
        //    }
        //}

        /// <summary>
        /// 查找单个数据
        /// </summary>
        /// <param name="expression">条件语句</param>
        /// <returns></returns>
        //public async Task<T> QuerySingleByExpression(Expression<Func<T, bool>> expression)
        //{
        //    return await AsyncCollection.FindAsync(expression).Result.FirstOrDefaultAsync();
        //}

        /// <summary>
        /// 查找数据数据
        /// </summary>
        /// <param name="expression">条件语句</param>
        /// <returns></returns>
        //public async Task<List<T>> FindData(Expression<Func<T, bool>> expression)
        //{
        //    return await AsyncCollection.Find(expression).ToListAsync();
        //}

        /// <summary>
        /// 查找带分页的数据
        /// </summary>
        /// <param name="expression">条件</param>
        /// <param name="IsPage">是否开启分页</param>
        /// <param name="intPageIndex">页码</param>
        /// <param name="intPageSize">每页数量</param>
        /// <param name="order">排序条件</param>
        /// <param name="isAsc">正序倒序</param>
        /// <returns></returns>
        //public async Task<IQueryable<T>> QueryCondition(Expression<Func<T, bool>> expression, bool IsPage, int PageIndex = 1, int PageSize = 20, Expression<Func<T, object>> order = null, bool isAsc = true)
        //{
        //    return await Task.Run(() =>
        //    {
        //        // var list = AsyncCollection.Find(expression).ToListAsync().Result.AsQueryable();
        //        var list = AsyncCollection.AsQueryable().Where(expression);

        //        if (order != null)
        //        {
        //            if (isAsc)
        //                list = list.OrderByDescending(order);
        //            else
        //                list = list.OrderBy(order);
        //        }

        //        if (IsPage)
        //            list = list.Skip((PageIndex - 1) * PageSize).Take(PageSize);

        //        return list;
        //    });
        //    // return AsyncCollection.Find(expression).ToListAsync().Result.AsQueryable();
        //}
        #endregion
    }
}
